home *** CD-ROM | disk | FTP | other *** search
/ MacWorld: Conference & Expo 2005 / Macworld Conference and Expo - Documentation CD-ROM (2004).iso / mac / Adobe Reader 6.0 / Adobe Reader 6.0.app / Contents / MacOS / xfdf2cos.xml < prev   
Extensible Markup Language  |  2004-01-30  |  34KB  |  1,052 lines

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!-- postprocess -->
  3. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  4. <xsl:output method="xml" encoding="UTF-8" indent="no" omit-xml-declaration="no"/>
  5.  
  6.     <!--    All this does is traverse a string of numbers and emit them
  7.             as a sequence of elements with a single attribute    -->
  8.     <xsl:template name="emitNumbers">
  9.         <xsl:param name="NumberString"/>
  10.         <xsl:variable name="DelimiterFound" select="contains($NumberString, ',')"/>
  11.         <xsl:variable name="NumberValue">
  12.             <xsl:choose>
  13.                 <xsl:when test="$DelimiterFound">
  14.                     <xsl:value-of select="number(substring-before($NumberString, ','))"/>
  15.                 </xsl:when>
  16.                 <xsl:otherwise>
  17.                     <xsl:value-of select="number($NumberString)"/>
  18.                 </xsl:otherwise>
  19.             </xsl:choose>
  20.         </xsl:variable>
  21.         <xsl:variable name="ElementName">
  22.             <xsl:choose>
  23.                 <xsl:when test="floor($NumberValue) = $NumberValue">INT</xsl:when>
  24.                 <xsl:otherwise>FIXED</xsl:otherwise>
  25.             </xsl:choose>
  26.         </xsl:variable>
  27.         <xsl:element name="{$ElementName}">
  28.             <xsl:attribute name="VAL">
  29.                 <xsl:value-of select="$NumberValue"/>
  30.             </xsl:attribute>
  31.         </xsl:element>
  32.         <xsl:if test="$DelimiterFound">
  33.             <xsl:call-template name="emitNumbers">
  34.                 <xsl:with-param name="NumberString"><xsl:value-of select="substring-after($NumberString, ',')"/></xsl:with-param>
  35.             </xsl:call-template>
  36.         </xsl:if>
  37.     </xsl:template>
  38.  
  39.     <!--    All this does is traverse a string of filters and emit them
  40.             as a sequence of elements with a single attribute    -->
  41.     <xsl:template name="emitFilters">
  42.         <xsl:param name="FilterList"/>
  43.         <xsl:variable name="DelimiterFound" select="contains($FilterList, ',')"/>
  44.         <xsl:variable name="FilterValue">
  45.             <xsl:choose>
  46.                 <xsl:when test="$DelimiterFound">
  47.                     <xsl:value-of select="substring-before($FilterList, ',')"/>
  48.                 </xsl:when>
  49.                 <xsl:otherwise>
  50.                     <xsl:value-of select="$FilterList"/>
  51.                 </xsl:otherwise>
  52.             </xsl:choose>
  53.         </xsl:variable>
  54.         <xsl:element name="NAME">
  55.             <xsl:attribute name="VAL">
  56.                 <xsl:value-of select="$FilterValue"/>
  57.             </xsl:attribute>
  58.         </xsl:element>
  59.         <xsl:if test="$DelimiterFound">
  60.             <xsl:call-template name="emitFilters">
  61.                 <xsl:with-param name="FilterList">
  62.                     <xsl:value-of select="substring-after($FilterList, ',')"/>
  63.                 </xsl:with-param>
  64.             </xsl:call-template>
  65.         </xsl:if>
  66.     </xsl:template>
  67.  
  68.     <!-- convert a hex digit into a decimal value -->
  69.     <xsl:template name="convertHexDigit">
  70.         <xsl:param name="HexChar"/>
  71.         <xsl:choose>
  72.             <xsl:when test="$HexChar='A'">10</xsl:when>
  73.             <xsl:when test="$HexChar='B'">11</xsl:when>
  74.             <xsl:when test="$HexChar='C'">12</xsl:when>
  75.             <xsl:when test="$HexChar='D'">13</xsl:when>
  76.             <xsl:when test="$HexChar='E'">14</xsl:when>
  77.             <xsl:when test="$HexChar='F'">15</xsl:when>
  78.             <xsl:otherwise><xsl:value-of select="$HexChar"/></xsl:otherwise>
  79.         </xsl:choose>
  80.     </xsl:template>
  81.  
  82.     <!-- generate a sequence of FIXED/INT nodes for each RGB value -->
  83.     <xsl:template name="convertHexColorToFloat">
  84.         <xsl:param name="HexString"/>
  85.         <xsl:if test="$HexString != ''">
  86.             <xsl:variable name="firstdigit">
  87.                 <xsl:call-template name="convertHexDigit">
  88.                     <xsl:with-param name="HexChar"><xsl:value-of select="substring($HexString, 1, 1)"/></xsl:with-param>
  89.                 </xsl:call-template>
  90.             </xsl:variable>
  91.             <xsl:variable name="seconddigit">
  92.                 <xsl:call-template name="convertHexDigit">
  93.                     <xsl:with-param name="HexChar"><xsl:value-of select="substring($HexString, 2, 1)"/></xsl:with-param>
  94.                 </xsl:call-template>
  95.             </xsl:variable>
  96.             <xsl:variable name="NumberValue">
  97.  
  98.                 <xsl:value-of select="(number($firstdigit) * 16 + number($seconddigit)) div 255"/>
  99.             </xsl:variable>
  100.             <xsl:variable name="ElementName">
  101.                 <xsl:choose>
  102.                     <xsl:when test="floor($NumberValue) = $NumberValue">INT</xsl:when>
  103.                     <xsl:otherwise>FIXED</xsl:otherwise>
  104.                 </xsl:choose>
  105.             </xsl:variable>
  106.             <xsl:element name="{$ElementName}">
  107.                 <xsl:attribute name="VAL">
  108.                     <xsl:choose>
  109.                         <xsl:when test="$ElementName = 'FIXED'">
  110.                             <!-- only put out color to six decimal places -->
  111.                             <xsl:value-of select="format-number($NumberValue, '0.0#####')"/>
  112.                         </xsl:when>
  113.                         <xsl:otherwise>
  114.                             <xsl:value-of select="$NumberValue"/>
  115.                         </xsl:otherwise>
  116.                     </xsl:choose>
  117.                 </xsl:attribute>
  118.             </xsl:element>
  119.             <xsl:call-template name="convertHexColorToFloat">
  120.                 <xsl:with-param name="HexString">
  121.                     <xsl:value-of select="substring($HexString, 3)"/>
  122.                 </xsl:with-param>
  123.             </xsl:call-template>
  124.         </xsl:if>
  125.     </xsl:template>
  126.  
  127.     <!-- map the flags to their corresponding integer values -->
  128.     <xsl:template name="mapFlags">
  129.         <xsl:param name="FlagValue"/>
  130.         <xsl:choose>
  131.             <xsl:when test="$FlagValue = 'invisible'">1</xsl:when>
  132.             <xsl:when test="$FlagValue = 'hidden'">2</xsl:when>
  133.             <xsl:when test="$FlagValue = 'print'">4</xsl:when>
  134.             <xsl:when test="$FlagValue = 'nozoom'">8</xsl:when>
  135.             <xsl:when test="$FlagValue = 'norotate'">16</xsl:when>
  136.             <xsl:when test="$FlagValue = 'noview'">32</xsl:when>
  137.             <xsl:when test="$FlagValue = 'readonly'">64</xsl:when>
  138.             <xsl:when test="$FlagValue = 'locked'">128</xsl:when>
  139.             <xsl:when test="$FlagValue = 'togglenoview'">256</xsl:when>
  140.         </xsl:choose>
  141.     </xsl:template>
  142.  
  143.     <!--    convert the string values of the flags
  144.             attribute into a bitfield value -->
  145.     <xsl:template name="convertFlags">
  146.         <xsl:param name="FlagString"/>
  147.         <xsl:variable name="DelimiterFound" select="contains($FlagString, ',')"/>
  148.         <xsl:variable name="FlagValue">
  149.             <xsl:choose>
  150.                 <xsl:when test="$DelimiterFound">
  151.                     <xsl:value-of select="substring-before($FlagString, ',')"/>
  152.                 </xsl:when>
  153.                 <xsl:otherwise>
  154.                     <xsl:value-of select="$FlagString"/>
  155.                 </xsl:otherwise>
  156.             </xsl:choose>
  157.         </xsl:variable>
  158.  
  159.         <xsl:variable name="CurrentValue">
  160.             <xsl:call-template name="mapFlags">
  161.                 <xsl:with-param name="FlagValue"><xsl:value-of select="$FlagValue"/></xsl:with-param>
  162.             </xsl:call-template>
  163.         </xsl:variable>
  164.  
  165.         <xsl:choose>
  166.             <xsl:when test="$DelimiterFound">
  167.                 <!-- recurse on the rest of the flags,
  168.                      summing the result on return to get the
  169.                      bitfield values -->
  170.                 <xsl:variable name="RestValue">
  171.                     <xsl:call-template name="convertFlags">
  172.                         <xsl:with-param name="FlagString" select="substring-after($FlagString, ',')"/>
  173.                     </xsl:call-template>
  174.                 </xsl:variable>
  175.                 <xsl:value-of select="number($CurrentValue) + $RestValue"/>
  176.             </xsl:when>
  177.             <xsl:otherwise>
  178.                 <xsl:value-of select="$CurrentValue"/>
  179.             </xsl:otherwise>
  180.         </xsl:choose>
  181.     </xsl:template>
  182.  
  183.     <!--    dump the data node into the stream! -->
  184.     <xsl:template name="emitData">
  185.         <xsl:param name="StreamData"/>
  186.  
  187.         <xsl:for-each select="$StreamData">
  188.             <xsl:element name="DATA">
  189.                 <xsl:attribute name="MODE">
  190.                     <xsl:value-of select="translate (@mode, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
  191.                 </xsl:attribute>
  192.                 <xsl:attribute name="ENCODING">
  193.                     <xsl:value-of select="translate (@encoding, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
  194.                 </xsl:attribute>
  195.                 <xsl:value-of select="."/>
  196.             </xsl:element>
  197.         </xsl:for-each>
  198.     </xsl:template>
  199.  
  200.     <xsl:template name="emitStream">
  201.         <xsl:param name="StreamData"/>
  202.         <xsl:param name="FilterData"/>
  203.         <xsl:param name="AnnotationType"/>
  204.  
  205.         <xsl:choose>
  206.             <xsl:when test="$AnnotationType = 'sound'">
  207.                 <xsl:element name="NAME">
  208.                     <xsl:attribute name="KEY">Type</xsl:attribute>
  209.                     <xsl:attribute name="VAL">Sound</xsl:attribute>
  210.                 </xsl:element>
  211.                 <xsl:element name="STREAM">
  212.                     <xsl:attribute name="KEY">Sound</xsl:attribute>
  213.                     <!--    fill in the content of the
  214.                             annotation define id later -->
  215.                     <xsl:attribute name="DEFINE"/>
  216.                     <xsl:apply-templates select="@length|../@encoding|../@rate|../@bits|../@channels|$FilterData"/>
  217.                     <xsl:call-template name="emitData">
  218.                         <xsl:with-param name="StreamData" select="$StreamData"/>
  219.                     </xsl:call-template>
  220.                 </xsl:element>
  221.             </xsl:when>
  222.  
  223.             <xsl:when test="$AnnotationType = 'fileattachment'">
  224.                 <xsl:choose>
  225.                     <xsl:when test="name() = 'data'">
  226.                         <xsl:element name="DICT">
  227.                             <xsl:attribute name="KEY">FS</xsl:attribute>
  228.                             <xsl:apply-templates select="../@file"/>
  229.                             <xsl:element name="NAME">
  230.                                 <xsl:attribute name="KEY">Type</xsl:attribute>
  231.                                 <xsl:attribute name="VAL">Filespec</xsl:attribute>
  232.                             </xsl:element>
  233.                             <xsl:element name="DICT">
  234.                                 <xsl:attribute name="KEY">EF</xsl:attribute>
  235.                                 <xsl:element name="STREAM">
  236.                                     <xsl:attribute name="KEY">F</xsl:attribute>
  237.                                     <!--    fill in the content of the
  238.                                             annotation define id later -->
  239.                                     <xsl:attribute name="DEFINE"/>
  240.                                     <xsl:apply-templates select="@length|../@mimetype|$FilterData"/>
  241.                                     <xsl:for-each select="..">
  242.                                         <xsl:if test="@creation|@modification|@checksum|@size|*[name()='resource']">
  243.                                             <xsl:element name="DICT">
  244.                                                 <xsl:attribute name="KEY">Params</xsl:attribute>
  245.                                                 <!-- using resource here will cause recursion -->
  246.                                                 <xsl:apply-templates select="@creation|@modification|@checksum|@size|*[name()='resource']"/>
  247.                                             </xsl:element>
  248.                                         </xsl:if>
  249.                                     </xsl:for-each>
  250.                                     <xsl:call-template name="emitData">
  251.                                         <xsl:with-param name="StreamData" select="$StreamData"/>
  252.                                     </xsl:call-template>
  253.                                 </xsl:element>
  254.                             </xsl:element>
  255.                         </xsl:element>
  256.                     </xsl:when>
  257.  
  258.                     <xsl:when test="name() = 'resource'">
  259.                         <xsl:element name="DICT">
  260.                             <xsl:attribute name="KEY">Mac</xsl:attribute>
  261.                             <xsl:apply-templates select="@subtype|@creator"/>
  262.                             <xsl:element name="STREAM">
  263.                                 <xsl:attribute name="KEY">ResFork</xsl:attribute>
  264.                                 <!--    fill in the content of the
  265.                                         annotation define id later -->
  266.                                 <xsl:attribute name="DEFINE"/>
  267.                                     <xsl:apply-templates select="@length|$FilterData"/>
  268.                                     <xsl:call-template name="emitData">
  269.                                         <xsl:with-param name="StreamData" select="$StreamData"/>
  270.                                     </xsl:call-template>
  271.                             </xsl:element>
  272.                         </xsl:element>
  273.                     </xsl:when>
  274.                 </xsl:choose>
  275.             </xsl:when>
  276.         </xsl:choose>
  277.     </xsl:template>
  278.  
  279.     <xsl:template match="/">
  280.         <xsl:element name="PDF">
  281.             <xsl:element name="CATALOG">
  282.                 <xsl:element name="DICT">
  283.                     <xsl:attribute name="DEFINE">1/0</xsl:attribute>
  284.                     <xsl:apply-templates/>
  285.                 </xsl:element>
  286.             </xsl:element>
  287.             <!-- just dropped this in -->
  288.             <INFO><NULL/></INFO>
  289.         </xsl:element>
  290.     </xsl:template>
  291.           
  292.     <xsl:template match="*">
  293.         <xsl:choose>
  294.             <xsl:when test="name() = 'xfdf'">
  295.                 <xsl:element name="DICT">
  296.                     <xsl:attribute name="KEY">FDF</xsl:attribute>
  297.                     <xsl:apply-templates/>
  298.                 </xsl:element>
  299.             </xsl:when>
  300.  
  301.             <xsl:when test="name() = 'appearance'">
  302.                 <xsl:element name="APPEARANCE">
  303.                     <xsl:value-of select="."/>
  304.                 </xsl:element>
  305.             </xsl:when>
  306.  
  307.             <!-- beginning of field handling -->
  308.  
  309.             <xsl:when test="name() = 'fields'">
  310.                 <xsl:element name="ARRAY">
  311.                     <xsl:attribute name="KEY">Fields</xsl:attribute>
  312.                     <xsl:apply-templates/>
  313.                 </xsl:element>
  314.             </xsl:when>
  315.  
  316.             <xsl:when test="name() = 'field'">
  317.                 <xsl:element name="DICT">
  318.                     <xsl:element name="STRING">
  319.                         <xsl:attribute name="KEY">T</xsl:attribute>
  320.                         <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  321.                         <xsl:value-of select="@name"/>
  322.                     </xsl:element>
  323.                     <xsl:choose>
  324.                         <!--    for some reason, the commented out
  325.                                 test doesn't work. the following one
  326.                                 does - they should be equivalent -->
  327.                         <!--<xsl:when test="field">-->
  328.                         <xsl:when test="*[name() = 'field']">
  329.                             <xsl:element name="ARRAY">
  330.                                 <xsl:attribute name="KEY">Kids</xsl:attribute>
  331.                                 <xsl:apply-templates/>
  332.                             </xsl:element>
  333.                         </xsl:when>
  334.                         <xsl:when test="count(*[name() = 'value']) > 1">
  335.                             <xsl:element name="ARRAY">
  336.                                 <xsl:attribute name="KEY">V</xsl:attribute>
  337.                                 <xsl:apply-templates/>
  338.                             </xsl:element>
  339.                         </xsl:when>
  340.                         <xsl:otherwise>
  341.                             <xsl:apply-templates/>
  342.                         </xsl:otherwise>
  343.                     </xsl:choose>
  344.                 </xsl:element>
  345.             </xsl:when>
  346.  
  347.             <xsl:when test="name() = 'value'">
  348.                 <xsl:element name="STRING">
  349.                     <xsl:attribute name="KEY">V</xsl:attribute>
  350.                     <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  351.                     <xsl:value-of select="text()"/>
  352.                 </xsl:element>
  353.             </xsl:when>
  354.  
  355.             <xsl:when test="name() = 'value-richtext'">
  356.                 <xsl:element name="STRING">
  357.                     <xsl:attribute name="KEY">RV</xsl:attribute>
  358.                     <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  359.                     <xsl:value-of select="text()"/>
  360.                 </xsl:element>
  361.             </xsl:when>
  362.  
  363.             <!-- end of field handling -->
  364.  
  365.             <!-- beginning of annotation handling -->
  366.             <xsl:when test="name() = 'annots'">
  367.                 <xsl:element name="ARRAY">
  368.                     <xsl:attribute name="KEY">Annots</xsl:attribute>
  369.                     <xsl:for-each select="*">
  370.                         <xsl:apply-templates select="."/>
  371.                         <xsl:for-each select="*[name() = 'popup']">
  372.                             <!--    fill in the content of the
  373.                                     popup reference later -->
  374.                             <xsl:element name="DICT">
  375.                                 <xsl:attribute name="REF"/>
  376.                             </xsl:element>
  377.                         </xsl:for-each>
  378.                     </xsl:for-each>
  379.                 </xsl:element>
  380.             </xsl:when>
  381.  
  382.             <xsl:when test="name() = 'f'">
  383.                 <xsl:element name="STRING">
  384.                     <xsl:attribute name="KEY">F</xsl:attribute>
  385.                     <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  386.                     <xsl:value-of select="@href"/>
  387.                 </xsl:element>
  388.                 <xsl:if test="not(../*[name()='ids'])">
  389.                     <!-- just dropped this in -->
  390.                     <ARRAY KEY="ID"><STRING/><STRING/></ARRAY>
  391.                 </xsl:if>
  392.             </xsl:when>
  393.  
  394.             <xsl:when test="name() = 'ids'">
  395.                 <xsl:element name="ARRAY">
  396.                     <xsl:attribute name="KEY">ID</xsl:attribute>
  397.                     <xsl:element name="STRING">
  398.                         <xsl:attribute name="ENCODING">HEX</xsl:attribute>
  399.                         <xsl:value-of select="@original"/>
  400.                     </xsl:element>
  401.                     <xsl:element name="STRING">
  402.                         <xsl:attribute name="ENCODING">HEX</xsl:attribute>
  403.                         <xsl:value-of select="@modified"/>
  404.                     </xsl:element>
  405.                 </xsl:element>
  406.             </xsl:when>
  407.  
  408.             <xsl:when test="name() = 'inklist'">
  409.                 <xsl:element name="ARRAY">
  410.                     <xsl:attribute name="KEY">InkList</xsl:attribute>
  411.                     <!--    don't process gesture by recursion here as
  412.                             this could blow the stack -->
  413.                     <xsl:for-each select="*">
  414.                         <xsl:element name="gesture">
  415.                             <xsl:value-of select="."/>
  416.                         </xsl:element>
  417.                     </xsl:for-each>
  418.                 </xsl:element>
  419.             </xsl:when>
  420.  
  421.             <!--    special case for freetext (on a round trip,
  422.                     this will appear as an attribute of the annotation,
  423.                     to be consistent with other annotations -->
  424.             <xsl:when test="name() = 'border'">
  425.                 <!--    this array is used by annotations
  426.                         using a legacy layout of border
  427.                         styles -->
  428.                 <xsl:element name="ARRAY">
  429.                     <xsl:attribute name="KEY">Border</xsl:attribute>
  430.                     <xsl:element name="INT">
  431.                         <xsl:attribute name="VAL">0</xsl:attribute>
  432.                     </xsl:element>
  433.                     <xsl:element name="INT">
  434.                         <xsl:attribute name="VAL">0</xsl:attribute>
  435.                     </xsl:element>
  436.                     <xsl:element name="INT">
  437.                         <xsl:attribute name="VAL">
  438.                             <xsl:value-of select="."/>
  439.                         </xsl:attribute>
  440.                     </xsl:element>
  441.                 </xsl:element>
  442.                 <xsl:element name="DICT">
  443.                     <xsl:attribute name="KEY">BS</xsl:attribute>
  444.                     <xsl:element name="INT">
  445.                         <xsl:attribute name="KEY">W</xsl:attribute>
  446.                         <xsl:attribute name="VAL">
  447.                             <xsl:value-of select="@width"/>
  448.                         </xsl:attribute>
  449.                     </xsl:element>
  450.                 </xsl:element>
  451.             </xsl:when>
  452.  
  453.             <xsl:when test="name() = 'vertices'">
  454.                 <!--    don't process vertices by recursion here as
  455.                         this could blow the stack -->
  456.                 <xsl:element name="vertices">
  457.                     <xsl:value-of select="translate(current(), ';', ',')"/>
  458.                 </xsl:element>
  459.             </xsl:when>
  460.  
  461.             <xsl:when test="name() = 'contents-richtext'">
  462.                 <xsl:element name="STRING">
  463.                     <xsl:attribute name="KEY">RC</xsl:attribute>
  464.                     <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  465.                     <xsl:value-of select="text()"/>
  466.                 </xsl:element>
  467.             </xsl:when>
  468.  
  469.             <xsl:when test="name() = 'contents'">
  470.                 <xsl:element name="STRING">
  471.                     <xsl:attribute name="KEY">Contents</xsl:attribute>
  472.                     <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  473.                     <xsl:value-of select="text()"/>
  474.                 </xsl:element>
  475.             </xsl:when>
  476.  
  477.             <xsl:when test="name() = 'defaultappearance'">
  478.                 <xsl:element name="STRING">
  479.                     <xsl:attribute name="KEY">DA</xsl:attribute>
  480.                     <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  481.                     <xsl:value-of select="."/>
  482.                 </xsl:element>
  483.             </xsl:when>
  484.  
  485.             <xsl:when test="name() = 'defaultstyle'">
  486.                 <xsl:element name="STRING">
  487.                     <xsl:attribute name="KEY">DS</xsl:attribute>
  488.                     <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  489.                     <xsl:value-of select="."/>
  490.                 </xsl:element>
  491.             </xsl:when>
  492.  
  493.             <!-- data from sound, attachments -->
  494.             <xsl:when test="name() = 'data' or name() = 'resource'">
  495.                 <xsl:call-template name="emitStream">
  496.                     <xsl:with-param name="StreamData" select="."/>
  497.                     <xsl:with-param name="FilterData" select="@filter"/>
  498.                     <xsl:with-param name="AnnotationType" select="name(..)"/>
  499.                 </xsl:call-template>
  500.             </xsl:when>
  501.  
  502.             <xsl:otherwise>
  503.                 <xsl:variable name="ParentNotAnnots" select="name(..) != 'annots'"/>
  504.                 <xsl:variable name="ElementName">
  505.                     <xsl:choose>
  506.                         <!--    most annotation names only need
  507.                                 the first character of the name
  508.                                 converted to upper case -->
  509.                         <!--    put in exceptions to rule here -->
  510.                         <xsl:when test="name() = 'strikeout'">
  511.                             <xsl:text>StrikeOut</xsl:text>
  512.                         </xsl:when>
  513.                         <xsl:when test="name() = 'fileattachment'">
  514.                             <xsl:text>FileAttachment</xsl:text>
  515.                         </xsl:when>
  516.                         <xsl:when test="name() = 'freetext'">
  517.                             <xsl:text>FreeText</xsl:text>
  518.                         </xsl:when>
  519.                         <xsl:when test="name() = 'polyline'">
  520.                             <xsl:text>PolyLine</xsl:text>
  521.                         </xsl:when>
  522.                         <xsl:otherwise>
  523.                             <xsl:variable name="StartAnnotChar">
  524.                                 <xsl:value-of select="translate (substring(name(), 1, 1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
  525.                             </xsl:variable>
  526.                             <xsl:value-of select="concat($StartAnnotChar, substring(name(), 2))"/>
  527.                         </xsl:otherwise>
  528.                     </xsl:choose>
  529.                 </xsl:variable>
  530.                 <xsl:element name="DICT">
  531.                     <xsl:if test="$ParentNotAnnots">
  532.                         <xsl:attribute name="KEY">
  533.                             <xsl:value-of select="$ElementName"/>
  534.                         </xsl:attribute>
  535.                     </xsl:if>
  536.                     <!--    fill in the content of the
  537.                             annotation define id later -->
  538.                     <xsl:attribute name="DEFINE"/>
  539.                     <xsl:element name="NAME">
  540.                         <xsl:attribute name="KEY">Type</xsl:attribute>
  541.                         <xsl:attribute name="VAL">Annot</xsl:attribute>
  542.                     </xsl:element>
  543.                     <xsl:element name="NAME">
  544.                         <xsl:attribute name="KEY">Subtype</xsl:attribute>
  545.                         <xsl:attribute name="VAL">
  546.                             <xsl:value-of select="$ElementName"/>
  547.                         </xsl:attribute>
  548.                     </xsl:element>
  549.                     <xsl:if test="$ParentNotAnnots">
  550.                         <xsl:element name="DICT">
  551.                             <xsl:attribute name="KEY">Parent</xsl:attribute>
  552.                             <!--    fill in the content of the
  553.                                     parent reference later -->
  554.                             <xsl:attribute name="REF"/>
  555.                         </xsl:element>
  556.                     </xsl:if>
  557.  
  558.                     <!--    handle width, style, intensity, dashes
  559.                             start, end, head, tail attributes separately
  560.                             from other attributes and nodes, as they
  561.                             need to be wrapped within other nodes -->
  562.                     <xsl:variable name="BorderEffect" select="@intensity|@style[. = 'cloudy']"/>
  563.                     <xsl:variable name="BorderStyle" select="@width|@dashes|@style[not(. = 'cloudy')]"/>
  564.                     <xsl:if test="string($BorderEffect) != ''">
  565.                         <xsl:element name="DICT">
  566.                             <xsl:attribute name="KEY">BE</xsl:attribute>
  567.                             <xsl:apply-templates select="$BorderEffect"/>
  568.                         </xsl:element>
  569.                     </xsl:if>
  570.                     <xsl:if test="string($BorderStyle) != ''">
  571.                         <!--    this array is used by annotations
  572.                                 using a legacy layout of border
  573.                                 styles -->
  574.                         <xsl:element name="ARRAY">
  575.                             <xsl:attribute name="KEY">Border</xsl:attribute>
  576.                             <xsl:call-template name="emitNumbers">
  577.                                 <xsl:with-param name="NumberString">
  578.                                     <!-- use radii of zero -->
  579.                                     <xsl:text>0,0,</xsl:text>
  580.                                     <xsl:choose>
  581.                                         <xsl:when test="@width">
  582.                                             <xsl:value-of select="@width"/>
  583.                                         </xsl:when>
  584.                                         <!-- default width of one -->
  585.                                         <xsl:otherwise>1</xsl:otherwise>
  586.                                     </xsl:choose>
  587.                                     <xsl:if test="@dashes">
  588.                                         <xsl:text>,</xsl:text>
  589.                                         <xsl:value-of select="@dashes"/>
  590.                                     </xsl:if>
  591.                                 </xsl:with-param>
  592.                             </xsl:call-template>
  593.                         </xsl:element>
  594.                         <xsl:element name="DICT">
  595.                             <xsl:attribute name="KEY">BS</xsl:attribute>
  596.                             <xsl:apply-templates select="$BorderStyle"/>
  597.                         </xsl:element>
  598.                     </xsl:if>
  599.                     <xsl:if test="@start|@end">
  600.                         <xsl:element name="ARRAY">
  601.                             <xsl:attribute name="KEY">L</xsl:attribute>
  602.                             <xsl:call-template name="emitNumbers">
  603.                                 <xsl:with-param name="NumberString">
  604.                                     <xsl:value-of select="@start"/>
  605.                                     <xsl:text>,</xsl:text>
  606.                                     <xsl:value-of select="@end"/>
  607.                             </xsl:with-param>
  608.                         </xsl:call-template>
  609.                         </xsl:element>
  610.                     </xsl:if>
  611.                     <xsl:if test="@head|@tail">
  612.                         <xsl:element name="ARRAY">
  613.                             <xsl:attribute name="KEY">LE</xsl:attribute>
  614.                             <!--    naming @head, @tail explicitly
  615.                                     ensures correct order -->
  616.                             <xsl:element name="NAME">
  617.                                 <xsl:attribute name="VAL">
  618.                                     <xsl:value-of select="@head"/>
  619.                                 </xsl:attribute>
  620.                             </xsl:element>
  621.                             <xsl:element name="NAME">
  622.                                 <xsl:attribute name="VAL">
  623.                                     <xsl:value-of select="@tail"/>
  624.                                 </xsl:attribute>
  625.                             </xsl:element>
  626.                         </xsl:element>
  627.                     </xsl:if>
  628.                     <xsl:apply-templates select="*[not(name()='resource')]|@*[not(
  629.                                 name() = 'width' or
  630.                                 name() = 'style' or
  631.                                 name() = 'dashes' or
  632.                                 name() = 'intensity' or
  633.                                 name() = 'start' or
  634.                                 name() = 'end' or
  635.                                 name() = 'head' or
  636.                                 name() = 'tail' or
  637.                                 name() = 'file' or
  638.                                 name() = 'length' or
  639.                                 name() = 'encoding' or
  640.                                 name() = 'rate' or
  641.                                 name() = 'bits' or
  642.                                 name() = 'channels' or
  643.                                 name() = 'creation' or
  644.                                 name() = 'modification' or
  645.                                 name() = 'checksum' or
  646.                                 name() = 'size' or
  647.                                 name() = 'mimetype')]"/>
  648.                 </xsl:element>
  649.             </xsl:otherwise>
  650.         </xsl:choose>
  651.     </xsl:template>
  652.           
  653.     <xsl:template match="@rotation">
  654.         <xsl:variable name="ElementName">
  655.             <xsl:choose>
  656.                 <xsl:when test="floor(number(.)) = number(.)">INT</xsl:when>
  657.                 <xsl:otherwise>FIXED</xsl:otherwise>
  658.             </xsl:choose>
  659.         </xsl:variable>
  660.         <xsl:element name="{$ElementName}">
  661.             <xsl:attribute name="KEY">Rotate</xsl:attribute>
  662.             <xsl:attribute name="VAL">
  663.                 <xsl:value-of select="."/>
  664.             </xsl:attribute>
  665.         </xsl:element>
  666.     </xsl:template>
  667.  
  668.     <xsl:template match="@rect">
  669.         <xsl:element name="ARRAY">
  670.             <xsl:attribute name="KEY">Rect</xsl:attribute>
  671.             <xsl:call-template name="emitNumbers">
  672.                 <xsl:with-param name="NumberString" select="."/>
  673.             </xsl:call-template>
  674.         </xsl:element>
  675.     </xsl:template>
  676.  
  677.     <xsl:template match="@inlinetextrect">
  678.         <xsl:element name="ARRAY">
  679.             <xsl:attribute name="KEY">InlineTextRect</xsl:attribute>
  680.             <xsl:call-template name="emitNumbers">
  681.                 <xsl:with-param name="NumberString" select="."/>
  682.             </xsl:call-template>
  683.         </xsl:element>
  684.     </xsl:template>
  685.  
  686.     <xsl:template match="@caretrect">
  687.         <xsl:element name="ARRAY">
  688.             <xsl:attribute name="KEY">CaretRect</xsl:attribute>
  689.             <xsl:call-template name="emitNumbers">
  690.                 <xsl:with-param name="NumberString" select="."/>
  691.             </xsl:call-template>
  692.         </xsl:element>
  693.     </xsl:template>
  694.  
  695.     <xsl:template match="@fringe">
  696.         <xsl:element name="ARRAY">
  697.             <xsl:attribute name="KEY">RD</xsl:attribute>
  698.             <xsl:call-template name="emitNumbers">
  699.                 <xsl:with-param name="NumberString" select="."/>
  700.             </xsl:call-template>
  701.         </xsl:element>
  702.     </xsl:template>
  703.  
  704.     <xsl:template match="@color">
  705.         <xsl:element name="ARRAY">
  706.             <xsl:attribute name="KEY">C</xsl:attribute>
  707.             <xsl:call-template name="convertHexColorToFloat">
  708.                 <xsl:with-param name="HexString" select="substring(current(), 2)"/>
  709.             </xsl:call-template>
  710.         </xsl:element>
  711.     </xsl:template>
  712.  
  713.     <xsl:template match="@interior-color">
  714.         <xsl:element name="ARRAY">
  715.             <xsl:attribute name="KEY">IC</xsl:attribute>
  716.             <xsl:call-template name="convertHexColorToFloat">
  717.                 <xsl:with-param name="HexString" select="substring(current(), 2)"/>
  718.             </xsl:call-template>
  719.         </xsl:element>
  720.     </xsl:template>
  721.  
  722.     <xsl:template match="@page">
  723.         <xsl:element name="INT">
  724.             <xsl:attribute name="KEY">Page</xsl:attribute>
  725.             <xsl:attribute name="VAL">
  726.                 <xsl:value-of select="."/>
  727.             </xsl:attribute>
  728.         </xsl:element>
  729.     </xsl:template>
  730.  
  731.     <xsl:template match="@encoding">
  732.         <xsl:element name="NAME">
  733.             <xsl:attribute name="KEY">E</xsl:attribute>
  734.             <xsl:attribute name="VAL">
  735.                 <xsl:choose>
  736.                     <xsl:when test="current() = 'raw'">Raw</xsl:when>
  737.                     <xsl:when test="current() = 'signed'">Signed</xsl:when>
  738.                     <xsl:when test="current() = 'mulaw'">muLaw</xsl:when>
  739.                     <xsl:when test="current() = 'alaw'">ALaw</xsl:when>
  740.                 </xsl:choose>
  741.             </xsl:attribute>
  742.         </xsl:element>
  743.     </xsl:template>
  744.  
  745.     <xsl:template match="@bits">
  746.         <xsl:element name="INT">
  747.             <xsl:attribute name="KEY">B</xsl:attribute>
  748.             <xsl:attribute name="VAL">
  749.                 <xsl:value-of select="."/>
  750.             </xsl:attribute>
  751.         </xsl:element>
  752.     </xsl:template>
  753.  
  754.     <xsl:template match="@rate">
  755.         <xsl:element name="INT">
  756.             <xsl:attribute name="KEY">R</xsl:attribute>
  757.             <xsl:attribute name="VAL">
  758.                 <xsl:value-of select="."/>
  759.             </xsl:attribute>
  760.         </xsl:element>
  761.     </xsl:template>
  762.  
  763.     <xsl:template match="@channels">
  764.         <xsl:element name="INT">
  765.             <xsl:attribute name="KEY">C</xsl:attribute>
  766.             <xsl:attribute name="VAL">
  767.                 <xsl:value-of select="."/>
  768.             </xsl:attribute>
  769.         </xsl:element>
  770.     </xsl:template>
  771.  
  772.     <xsl:template match="@size">
  773.         <xsl:element name="INT">
  774.             <xsl:attribute name="KEY">Size</xsl:attribute>
  775.             <xsl:attribute name="VAL"><xsl:value-of select="."/></xsl:attribute>
  776.         </xsl:element>
  777.     </xsl:template>
  778.  
  779.     <xsl:template match="@length">
  780.         <xsl:element name="INT">
  781.             <xsl:attribute name="KEY">Length</xsl:attribute>
  782.             <xsl:attribute name="VAL"><xsl:value-of select="."/></xsl:attribute>
  783.         </xsl:element>
  784.     </xsl:template>
  785.  
  786.     <xsl:template match="@flags">
  787.         <xsl:element name="INT">
  788.             <xsl:attribute name="KEY">F</xsl:attribute>
  789.             <xsl:attribute name="VAL">
  790.                 <xsl:call-template name="convertFlags">
  791.                     <xsl:with-param name="FlagString" select="."/>
  792.                 </xsl:call-template>
  793.             </xsl:attribute>
  794.         </xsl:element>
  795.     </xsl:template>
  796.  
  797.     <xsl:template match="@modification">
  798.         <xsl:element name="STRING">
  799.             <xsl:attribute name="KEY">ModDate</xsl:attribute>
  800.             <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  801.             <xsl:value-of select="."/>
  802.         </xsl:element>
  803.     </xsl:template>
  804.  
  805.     <xsl:template match="@date">
  806.         <xsl:element name="STRING">
  807.             <xsl:attribute name="KEY">M</xsl:attribute>
  808.             <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  809.             <xsl:value-of select="."/>
  810.         </xsl:element>
  811.     </xsl:template>
  812.  
  813.     <xsl:template match="@creationdate|@creation">
  814.         <xsl:element name="STRING">
  815.             <xsl:attribute name="KEY">CreationDate</xsl:attribute>
  816.             <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  817.             <xsl:value-of select="."/>
  818.         </xsl:element>
  819.     </xsl:template>
  820.  
  821.     <xsl:template match="@title">
  822.         <xsl:element name="STRING">
  823.             <xsl:attribute name="KEY">T</xsl:attribute>
  824.             <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  825.             <xsl:value-of select="."/>
  826.         </xsl:element>
  827.     </xsl:template>
  828.  
  829.     <xsl:template match="@name">
  830.         <xsl:element name="STRING">
  831.             <xsl:attribute name="KEY">NM</xsl:attribute>
  832.             <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  833.             <xsl:value-of select="."/>
  834.         </xsl:element>
  835.     </xsl:template>
  836.  
  837.     <xsl:template match="@inreplyto">
  838.         <xsl:element name="STRING">
  839.             <xsl:attribute name="KEY">IRT</xsl:attribute>
  840.             <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  841.             <xsl:value-of select="."/>
  842.         </xsl:element>
  843.     </xsl:template>
  844.  
  845.     <xsl:template match="@width">
  846.         <xsl:element name="INT">
  847.             <xsl:attribute name="KEY">W</xsl:attribute>
  848.             <xsl:attribute name="VAL">
  849.                 <xsl:value-of select="."/>
  850.             </xsl:attribute>
  851.         </xsl:element>
  852.     </xsl:template>
  853.  
  854.     <xsl:template match="@style">
  855.         <xsl:element name="NAME">
  856.             <xsl:attribute name="KEY">S</xsl:attribute>
  857.             <xsl:attribute name="VAL">
  858.                 <xsl:choose>
  859.                     <xsl:when test="current() = 'solid'">S</xsl:when>
  860.                     <xsl:when test="current() = 'dash'">D</xsl:when>
  861.                     <xsl:when test="current() = 'bevelled'">B</xsl:when>
  862.                     <xsl:when test="current() = 'inset'">I</xsl:when>
  863.                     <xsl:when test="current() = 'underline'">U</xsl:when>
  864.                     <xsl:when test="current() = 'cloudy'">C</xsl:when>
  865.                 </xsl:choose>
  866.             </xsl:attribute>
  867.         </xsl:element>
  868.     </xsl:template>
  869.  
  870.     <xsl:template match="@dashes">
  871.         <xsl:element name="ARRAY">
  872.             <xsl:attribute name="KEY">D</xsl:attribute>
  873.                 <xsl:call-template name="emitNumbers">
  874.                     <xsl:with-param name="NumberString">
  875.                         <xsl:value-of select="."/>
  876.                     </xsl:with-param>
  877.                 </xsl:call-template>
  878.         </xsl:element>
  879.     </xsl:template>
  880.  
  881.     <xsl:template match="@intensity">
  882.         <xsl:element name="INT">
  883.             <xsl:attribute name="KEY">I</xsl:attribute>
  884.             <xsl:attribute name="VAL">
  885.                 <xsl:value-of select="."/>
  886.             </xsl:attribute>
  887.         </xsl:element>
  888.     </xsl:template>
  889.  
  890.     <xsl:template match="@subject">
  891.         <xsl:element name="STRING">
  892.             <xsl:attribute name="KEY">Subj</xsl:attribute>
  893.             <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  894.             <xsl:value-of select="."/>
  895.         </xsl:element>
  896.     </xsl:template>
  897.  
  898.     <xsl:template match="@icon">
  899.         <xsl:element name="NAME">
  900.             <xsl:attribute name="KEY">Name</xsl:attribute>
  901.             <xsl:attribute name="VAL"><xsl:value-of select="."/></xsl:attribute>
  902.         </xsl:element>
  903.     </xsl:template>
  904.  
  905.     <xsl:template match="@open">
  906.         <xsl:element name="BOOL">
  907.             <xsl:attribute name="KEY">Open</xsl:attribute>
  908.             <xsl:attribute name="VAL">
  909.                 <xsl:choose>
  910.                     <xsl:when test="current()='yes'">true</xsl:when>
  911.                     <xsl:otherwise>false</xsl:otherwise>
  912.                 </xsl:choose>
  913.             </xsl:attribute>
  914.         </xsl:element>
  915.     </xsl:template>
  916.  
  917.     <xsl:template match="@opacity">
  918.         <xsl:element name="FIXED">
  919.             <xsl:attribute name="KEY">CA</xsl:attribute>
  920.             <xsl:attribute name="VAL"><xsl:value-of select="."/></xsl:attribute>
  921.         </xsl:element>
  922.     </xsl:template>
  923.  
  924.     <xsl:template match="@justification">
  925.         <xsl:element name="INT">
  926.             <xsl:attribute name="KEY">Q</xsl:attribute>
  927.             <xsl:attribute name="VAL">
  928.                 <xsl:choose>
  929.                     <xsl:when test="current() = 'left'">0</xsl:when>
  930.                     <xsl:when test="current() = 'centered'">1</xsl:when>
  931.                     <xsl:when test="current() = 'right'">2</xsl:when>
  932.                 </xsl:choose>
  933.             </xsl:attribute>
  934.         </xsl:element>
  935.     </xsl:template>
  936.  
  937.     <xsl:template match="@coords">
  938.         <!--    don't process coords by recursion here as
  939.                 this could blow the stack -->
  940.         <xsl:element name="quadpoints">
  941.             <xsl:value-of select="."/>
  942.         </xsl:element>
  943.     </xsl:template>
  944.  
  945.     <xsl:template match="@state">
  946.         <xsl:element name="STRING">
  947.             <xsl:attribute name="KEY">State</xsl:attribute>
  948.             <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  949.             <xsl:value-of select="."/>
  950.         </xsl:element>
  951.     </xsl:template>
  952.  
  953.     <xsl:template match="@statemodel">
  954.         <xsl:element name="STRING">
  955.             <xsl:attribute name="KEY">StateModel</xsl:attribute>
  956.             <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  957.             <xsl:value-of select="."/>
  958.         </xsl:element>
  959.     </xsl:template>
  960.  
  961.     <xsl:template match="@checksum">
  962.         <xsl:element name="STRING">
  963.             <xsl:attribute name="KEY">CheckSum</xsl:attribute>
  964.             <xsl:attribute name="ENCODING">HEX</xsl:attribute>
  965.             <xsl:value-of select="."/>
  966.         </xsl:element>
  967.     </xsl:template>
  968.  
  969.     <xsl:template match="@mimetype">
  970.         <xsl:element name="NAME">
  971.             <xsl:attribute name="KEY">Subtype</xsl:attribute>
  972.             <xsl:attribute name="VAL">
  973.                 <xsl:value-of select="."/>
  974.             </xsl:attribute>
  975.         </xsl:element>
  976.     </xsl:template>
  977.  
  978.     <xsl:template match="@file">
  979.         <xsl:element name="STRING">
  980.             <xsl:attribute name="KEY">F</xsl:attribute>
  981.             <xsl:attribute name="ENCODING">ASCII</xsl:attribute>
  982.             <xsl:value-of select="."/>
  983.         </xsl:element>
  984.     </xsl:template>
  985.  
  986.     <xsl:template match="@symbol">
  987.         <xsl:element name="NAME">
  988.             <xsl:attribute name="KEY">Sy</xsl:attribute>
  989.             <xsl:attribute name="VAL">
  990.                 <xsl:choose>
  991.                     <xsl:when test=". = 'none'"></xsl:when>
  992.                     <xsl:when test=". = 'paragraph'">P</xsl:when>
  993.                     <xsl:when test=". = 'space'">S</xsl:when>
  994.                 </xsl:choose>
  995.             </xsl:attribute>
  996.         </xsl:element>
  997.     </xsl:template>
  998.  
  999.     <xsl:template match="@filter">
  1000.         <xsl:choose>
  1001.  
  1002.             <!-- more than one filter -->
  1003.             <xsl:when test="contains(., ',')">
  1004.                 <xsl:element name="ARRAY">
  1005.                     <xsl:attribute name="KEY">Filter</xsl:attribute>
  1006.                     <xsl:call-template name="emitFilters">
  1007.                         <xsl:with-param name="FilterList">
  1008.                             <xsl:value-of select="."/>
  1009.                         </xsl:with-param>
  1010.                     </xsl:call-template>
  1011.                 </xsl:element>
  1012.             </xsl:when>
  1013.  
  1014.             <!-- just one filter -->
  1015.             <xsl:otherwise>
  1016.                 <xsl:element name="NAME">
  1017.                     <xsl:attribute name="KEY">Filter</xsl:attribute>
  1018.                     <xsl:attribute name="VAL">
  1019.                         <xsl:value-of select="."/>
  1020.                     </xsl:attribute>
  1021.                 </xsl:element>
  1022.             </xsl:otherwise>
  1023.         </xsl:choose>
  1024.     </xsl:template>
  1025.  
  1026.     <!-- Mac specific attributes of a file attachment -->
  1027.  
  1028.     <xsl:template match="@subtype">
  1029.         <xsl:element name="INT">
  1030.             <xsl:attribute name="KEY">Subtype</xsl:attribute>
  1031.             <xsl:attribute name="VAL">
  1032.                 <xsl:value-of select="."/>
  1033.             </xsl:attribute>
  1034.         </xsl:element>
  1035.     </xsl:template>
  1036.  
  1037.     <xsl:template match="@creator">
  1038.         <xsl:element name="INT">
  1039.             <xsl:attribute name="KEY">Creator</xsl:attribute>
  1040.             <xsl:attribute name="VAL">
  1041.                 <xsl:value-of select="."/>
  1042.             </xsl:attribute>
  1043.         </xsl:element>
  1044.     </xsl:template>
  1045.  
  1046.     <!-- end of annotation handling -->
  1047.  
  1048.     <!-- get rid of any extraneous text nodes and attributes -->
  1049.     <xsl:template match="text()|@*"/>
  1050.  
  1051. </xsl:stylesheet>
  1052.